package com.example.bitmapandcachedemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.LruCache;
import android.widget.ImageView;

import com.example.bitmapandcachedemo.imageloader.DiskLruCache;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class CacheActivity extends AppCompatActivity {

    private Context mContext;
    private ImageView mImageView;
    private LruCache<String, Bitmap> mMemoryCache;
    private DiskLruCache mDiskLruCache;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cache);
        mImageView = findViewById(R.id.image);
    }

    private void init() {
        int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
        int cacheSize = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
            }
        };
    }

    private Bitmap getBitmap(String key) {
        return mMemoryCache.get(key);
    }

    private void putBitmap(String key, Bitmap bitmap) {
        mMemoryCache.put(key, bitmap);
    }

    private static final long DISK_CACHE_SIZE = 1024 * 1024 * 50;
    private static final int DISK_CAHCE_INDEX = 0;
    private static final int IO_BUFFER_SIZE = 1024;
    private File diskCacheDir = getDiskCacheDir(mContext, "bitmap");

    private void initDiskLruCache() throws IOException {
        if (!diskCacheDir.exists()) {
            diskCacheDir.mkdirs();
        }
        mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1, DISK_CACHE_SIZE);
    }


    private File getDiskCacheDir(Context context, String str) {
        return null;
    }

    private String hashKeyFromUrl(String url) {
        String cacheKey = "";
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(url.getBytes());
            cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return cacheKey;
    }


    private String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    private OutputStream getOutputStreamFromDiskLruCache(String url) {
        try {
            String key  = hashKeyFromUrl(url);
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);
            OutputStream outputStream = editor.newOutputStream(DISK_CAHCE_INDEX);
            if (downloadUrlToStream(url, outputStream)) {
                editor.commit();
            } else {
                editor.abort();
            }
            mDiskLruCache.flush();
            return outputStream;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
        HttpURLConnection urlConnection = null;
        BufferedOutputStream out = null;
        BufferedInputStream in = null;

        try {
            final URL url = new URL(urlString);
            urlConnection = (HttpURLConnection) url.openConnection();
            in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE);
            out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
            int b;
            while ((b = in.read()) != -1) {
                out.write(b);
            }
            return true;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private Bitmap getBitmapFromDiskCache(String url, int reqWidth, int reqHeight) throws IOException {
        Bitmap bitmap = null;
        String key = hashKeyFromUrl(url);
        DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
        if (snapshot != null) {
            FileInputStream inputStream = (FileInputStream) snapshot.getInputStream(DISK_CAHCE_INDEX);
            FileDescriptor fileDescriptor = inputStream.getFD();
            bitmap = decodeSampledBitmapFileDescriptor(fileDescriptor, reqWidth, reqHeight);
            if (bitmap != null) {
                addBitmapToMemoryCache(key, bitmap);
            }

        }
        return bitmap;
    }

    private void addBitmapToMemoryCache(String key, Bitmap bitmap) {

    }

    private Bitmap decodeSampledBitmapFileDescriptor(FileDescriptor fileDescriptor, int reqWidth, int reqHeight) {
        return null;
    }

}
